import 'package:my_flutter_core/services/route_map_manager.dart';

/// IMPORTANT!!!
/// Always keep it in mind that permission / authentication / authorization MUST be applied on server side first.
/// Any client side check is for user experience ONLY.
/// NEVER TRUST CLIENT!
class RouteMapService {
  /// Extracts role names from request map config attribute.
  /// Example: hasRole('admin'), hasAnyRole('reporter', 'planner').
  /// Returns string list of role name.
  static List<String> extractRoleNames(String configAttribute) {
    List<String> roleNames = [];

    final exp = RegExp(
        '(?:${RouteMapManager.hasRolePrefix}|${RouteMapManager.hasAnyRolePrefix}|${RouteMapManager.hasNoRolePrefix}|${RouteMapManager.hasNoAnyRolePrefix})((.+))');

    // This would match the role names, like 'admin' or 'reporter', 'planner'.
    final match = exp.allMatches(configAttribute);

    // If match found.
    if (match.isNotEmpty) {
      if (match.first.groupCount == 2) {
        // Removes all single quotes.
        var matchedRoles = match.first.group(1)!.replaceAll('\'', '');

        // Removes all double quotes.
        matchedRoles = matchedRoles.replaceAll('"', '');

        // Removes all openning parentheses.
        matchedRoles = matchedRoles.replaceAll('(', '');

        // Removes all closing parentheses.
        matchedRoles = matchedRoles.replaceAll(')', '');

        // Splits the string by comma.
        final splitedRoles = matchedRoles.split(',');

        // Trims space for each role name.
        for (final p in splitedRoles) {
          roleNames.add(p.trim());
        }
      }
    }

    return roleNames;
  }

  /// Checks if security request map configAttribute contains any role in roleNames.
  static bool containsAnyRoleInConfigAttribute(
      List<String> roleNames, String configAttribute) {
    return _containsAnyRoleInConfigRoleNames(
        roleNames, extractRoleNames(configAttribute));
  }

  /// Checks if configuredRoleNames contains any role in roleNames.
  static bool _containsAnyRoleInConfigRoleNames(
      List<String> roleNames, List<String> configRoleNames) {
    var containsAnyRole = false;

    for (String roleName in roleNames) {
      for (String configRoleName in configRoleNames) {
        if (roleName.toLowerCase() == configRoleName.toLowerCase()) {
          containsAnyRole = true;
          break;
        }
      }
    }

    return containsAnyRole;
  }
}
